package com.gali.juc;

import java.lang.ref.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: gali
 * @Date: 2022-08-24 21:18
 * @Description:
 */
class myObject{
    @Override
    protected void finalize() throws Throwable {
        System.out.println("-----invoke finalize method-----");
    }
}
public class ReferenceDemo {
    public static void main(String[] args) {
//        strongReference();
//        softReference();
//        weakReference();
        myObject myObject = new myObject();
        ReferenceQueue<myObject> queue=new ReferenceQueue<>();
        PhantomReference<myObject> reference=new PhantomReference<>(myObject,queue);

        System.out.println(reference.get());  //总是null
        List<byte[]> list = new ArrayList<>();
        new Thread(()->{
            while (true) {
                list.add(new byte[1 * 1024 * 1024]);
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"a").start();

        new Thread(()->{
            while (true){
                Reference<? extends myObject> poll = queue.poll();
                if (poll!=null){
                    System.out.println("有虚对象被回收");
                    break;
                }
            }
        },"b").start();
    }

    private static void weakReference() {
        WeakReference<myObject> weakReference=new WeakReference<>(new myObject());
        System.out.println("gc before-----"+weakReference.get());
        System.gc();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("gc after-----"+weakReference.get());
    }

    private static void softReference() {
        SoftReference<myObject> myObjectSoftReference = new SoftReference<>(new myObject());
        System.out.println("softReference:"+myObjectSoftReference.get());
        System.gc();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("-----gc after内存够用："+myObjectSoftReference.get());
    }

    private static void strongReference() {
        myObject myObject = new myObject();
        System.out.println("gc before \t"+myObject);

        myObject=null;
        System.gc();//人工开启gc垃圾回收
        System.out.println("gc after \t"+myObject);
    }
}
